/*
 * Copyright (c) 2009 John Pritchard, WTKX Project Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wtkx.in;

import wtkx.Application;
import wtkx.Component;
import wtkx.Scene;

import jbxml.Dictionary;
import jbxml.Properties;

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.URL;

/**
 * Application frame 
 *
 * @author jdp
 */
public class Fullscreen 
    extends java.awt.Dialog
    implements BackingStore.Container
{
    private final static long EVENT_MASK =  (AWTEvent.WINDOW_EVENT_MASK
                                           | AWTEvent.WINDOW_STATE_EVENT_MASK
                                           | AWTEvent.COMPONENT_EVENT_MASK
                                           | AWTEvent.FOCUS_EVENT_MASK
                                           | AWTEvent.MOUSE_EVENT_MASK
                                           | AWTEvent.MOUSE_MOTION_EVENT_MASK
                                           | AWTEvent.MOUSE_WHEEL_EVENT_MASK
                                           | AWTEvent.KEY_EVENT_MASK);


    protected final Scene scene;

    protected Screen screen;

    protected Awtk awtk;

    protected BackingStore.Component canvas;


    public Fullscreen(Screen screen, Dictionary<String,String> properties, Application application) {
        super(new java.awt.Frame(),wtkx.Version.Full,false,screen.getConfiguration());
        if (null != screen && null != properties){

            if (null == application)
                application = this.newMainScript();

            this.screen = screen;

            this.enableEvents(EVENT_MASK);
            this.setFocusTraversalKeysEnabled(false);
            this.setUndecorated(true);
            this.setLayout(new LM());

            this.canvas = this.ctorNewCanvas();

            this.canvas.setSize(this.getSize());

            java.awt.Component component = (java.awt.Component)this.canvas;
            this.add(component);

            this.setFocusTraversalPolicy(FocusTP.Instance);

            this.scene = new Scene(properties,application,this,component);
        }
        else
            throw new IllegalArgumentException();
    }

    protected Application newMainScript(){
        return new MainScript();
    }
    protected BackingStore.Component ctorNewCanvas(){
        return new Canvas();
    }
    public void init(){

        this.awtk = new Awtk(this,this.canvas,scene);

        this.scene.init(this.awtk);

        this.canvas.init(this.awtk,this.screen);
    }
    @Override
    public void processWindowEvent(WindowEvent event) {
        super.processWindowEvent(event);

        switch(event.getID()) {
        case WindowEvent.WINDOW_OPENED:

            this.init();

            this.canvas.start();

            this.scene.startup();

            break;

        case WindowEvent.WINDOW_CLOSING:

            this.canvas.stop();

            this.scene.shutdown();

            this.canvas.destroy();

            this.awtk.destroy();

            java.awt.Window window = event.getWindow();
            window.setVisible(false);
            window.dispose();

            break;

        case WindowEvent.WINDOW_CLOSED:
            System.exit(0);
            break;
        }
    }
    @Override
    protected void processWindowStateEvent(WindowEvent event) {
        super.processWindowStateEvent(event);

        switch(event.getID()) {
        case WindowEvent.WINDOW_ICONIFIED:

            this.scene.suspend();
            break;

        case WindowEvent.WINDOW_DEICONIFIED:

            this.scene.resume();
            break;
        }
    }
    @Override
    protected void processComponentEvent(ComponentEvent event) {
        super.processComponentEvent(event);
        Awtk awtk = this.awtk;
        if (null != awtk)
            awtk.processComponentEvent(event);
    }
    @Override
    protected void processFocusEvent(FocusEvent event) {
        super.processFocusEvent(event);
        Awtk awtk = this.awtk;
        if (null != awtk)
            awtk.processFocusEvent(event);
    }
    @Override
    protected void processMouseEvent(MouseEvent event) {
        super.processMouseEvent(event);
        Awtk awtk = this.awtk;
        if (null != awtk)
            awtk.processMouseEvent(event);
    }
    @Override
    protected void processMouseMotionEvent(MouseEvent event) {
        super.processMouseMotionEvent(event);
        Awtk awtk = this.awtk;
        if (null != awtk)
            awtk.processMouseMotionEvent(event);
    }
    @Override
    protected void processMouseWheelEvent(MouseWheelEvent event) {
        super.processMouseWheelEvent(event);
        Awtk awtk = this.awtk;
        if (null != awtk)
            awtk.processMouseWheelEvent(event);
    }
    @Override
    protected void processKeyEvent(KeyEvent event) {
        super.processKeyEvent(event);
        Awtk awtk = this.awtk;
        if (null != awtk)
            awtk.processKeyEvent(event);
    }

    /*
     * 
     */

    protected static final String D_ARGUMENT = "-d";
    protected static final String P_ARGUMENT = "-p";

    public static void main(String[] args) throws Exception {

        int d = 0;
        String applicationClassName = null;

        Properties properties = new Properties();

        for (int i = 0, n = args.length; i < n; i++) {
            String arg = args[i];

            if (arg.equals(D_ARGUMENT)) {
                String value = args[++i];
                d = Integer.parseInt(value);
            }
            else if (arg.equals(P_ARGUMENT)) {
                String filename = args[++i];
                properties.load(filename);
            }
            else {
                if (null == applicationClassName)
                    applicationClassName = arg;
                else {
                    String value = args[++i];
                    properties.put(arg, value);
                }
            }
        }

        Screen screen = new Screen(d);

        Application application = null;

        if (null == applicationClassName) {
            MetaService service = new MetaService();
            if (service.hasNotValue()){
                System.out.println("Usage");
                System.out.println();
                System.out.println("  wtkx.in.Fullscreen [-d d] [-p app.properties] ");
                System.out.println("          (file.wtkx|pkg.app.ClassName) [prop-name prop-value]*");
                System.out.println();
                System.out.println("Description");
                System.out.println();
                System.out.println("  Scene in a full screen window without decoration.");
                System.out.println();
                System.out.println("  Hardware screen devices (physical monitors) are numbered from");
                System.out.println("  zero.  The default 'd' value is zero.  If you have two screens,");
                System.out.println("  then valid values for 'd' would be zero and one.");
                System.out.println();
                System.out.println("  If your application extends 'wtkx.in.Script', then you want");
                System.out.println("  a button with 'onclick' value 'systemExit' (or similar).");
                System.out.println();
                System.exit(1);
                return;
            }
            else
                applicationClassName = service.value;
        } 

        try {
            Class applicationClass = Class.forName(applicationClassName);
            application = (Application)applicationClass.newInstance();
        }
        catch (ClassNotFoundException exc){
            File test = new File(applicationClassName);
            if (test.isFile()){
                properties.put(Application.PARAM,applicationClassName);
            }
            else
                throw exc;
        }

        Fullscreen frame = new Fullscreen(screen,properties,application);
        Rectangle display = screen.display;
        frame.setLocation(display.x, display.y);
        frame.setSize(display.width, display.height);
        frame.setVisible(true);
    }

}
